<?php
// 接口-销售单接口
namespace interface\v1;

use verify;

class saleOrderClass extends index
{
    private const page        = 'saleOrder';
    private const table       = 'sale_order';
    private const tableMx     = 'sale_order_detail';
    private const title       = '销售单';
    private const tableTarget = 'kehu';

    public function search()
    {
        $this->code         = 1;
        $this->resp['data'] = [
            'orderBy' => [
                '创建时间降序',
                '创建时间升序',
                '单据日期降序',
                '单据日期升序',
                '交货日期降序',
                '交货日期升序',
            ],
            'search'  => [
                'type'         => [
                    'key'   => 'type',
                    'name'  => '单据类型',
                    'array' => [
                        '销货', '退货',
                    ],
                ],
                'recordDate'   => [
                    'key'   => 'recordDate',
                    'name'  => '单据日期',
                    'array' => $this->timeOption,
                ],
                'deliveryDate' => [
                    'key'   => 'deliveryDate',
                    'name'  => '交货日期',
                    'array' => $this->timeOption,
                ],
                'state'        => [
                    'key'   => 'state',
                    'name'  => '状态',
                    'array' => [
                        '草稿', '待确认', '已确认',
                    ],
                ],
            ],

        ];
    }

    /**
     * 编辑页所需数据
     *
     * @return void
     */
    public function editOption(): void
    {
        $this->code = 1;
        $this->resp['data'] = [
            'deliveryMethod'=>[['value'=>'1','text'=>'自提'],['value'=>'2','text'=>'配送']],
            'isTax'=>[['value'=>'1','text'=>'是'],['value'=>'0','text'=>'否']],
            'settlement'=>array_merge(para('supplierSettlement', '，'), ['月结']),
        ];
    }

    /**
     * 列表
     *
     * @return void
     */
    public function list()
    {
        $where = '';
        if ($this->post('name')) {
            $where .= " AND khid in (SELECT khid FROM kehu WHERE companyName like '%" . $this->post('name') . "%' ) ";
        }
        //获取查询结果
        $where .= search([
            "="    => [
                'coid'  => self::$coid,
                'type'  => $this->post('type'),
                'state' => $this->post('state'),
            ],
            'like' => [
                'orderNo' => $this->post('orderNo'),
            ],
        ]);

        //单据日期
        if ($this->post('recordDate')) {
            $where .= self::miniTimeComparison($this->post('recordDate'), 'date', 'recordDate');
        }
        // 交货日期
        if ($this->post('deliveryDate')) {
            $where .= self::miniTimeComparison($this->post('deliveryDate'), 'date', 'deliveryDate');
        }
        $orderBy      = $this->post('orderBy') ?: '创建时间降序';
        $orderByArray = $this->orderBy([
            "search"  => $orderBy,
            "default" => "创建时间降序",
            "array"   => [
                "time"         => ["asc" => "创建时间升序", "desc" => "创建时间降序", "site" => 1],
                "recordDate"   => ["asc" => "单据时间升序", "desc" => "单据时间降序", "site" => 2],
                "deliveryDate" => ["asc" => "交货时间升序", "desc" => "交货时间降序", "site" => 3],
            ],
        ]);
        $page         = $this->page(["table" => self::table, "where" => $where, "order" => $orderByArray['orderBy']]);
        //数据分析
        $data['result'] = [];
        foreach ($page['array'] as $array) {
            $target           = query(self::tableTarget, " khid = '$array[khid]' ");
            $result           = find([
                'table'  => self::tableMx,
                'field'  => ' any_value(materialId) as materialId, IFNULL(sum(num), 0) as total ',
                'single' => " orderId = '$array[id]' ",
            ]);
            $material         = query('material', " id = '$result[materialId]' ");
            $data['result'][] = [
                "id"       => $array['id'],
                'orderNo'  => $array['orderNo'],
                'type'     => $array['type'],
                'target'   => $target['companyName'] ?: '',
                'material' => $material['name'] . '等' . $result['total'] . $material['unit'],
                "state"    => $array['state'],
                'manager'  => self::findStaff($array['manager']),
                'money'    => $array['money'],
                'time'     => self::formatDate($array['time'], 'Y/m/d'),
            ];
        }
        $data['page']    = $page['para'];
        $data['orderBy'] = $orderBy;
        $data['sql']     = $page['sql'];
        //返回
        $this->code         = 1;
        $this->resp['data'] = $data;
    }


    /**
     * 选择物料
     */
    public function material()
    {
        $materialId = $this->post('materialId') ? explode(',', $this->post('materialId')) : [];
        $where      = " 1=1 and a.id not in ('" . implode("','", $materialId) . "')";
        $and        = " AND a.coid = '" . self::$coid . "' ";
        if ($this->post('wd')) {
            $and .= " AND (a.name like '%{$this->post('wd')}%' OR code like '%{$this->post('wd')}%') ";
        }
        $equal   = [
            'a.state' => '启用',
        ];
        $where   .= search(["=" => $equal]) . $and;
        $orderBy = $this->orderBy([
            "search"  => $this->post('orderBy') ?: null,
            "default" => "创建时间降序",
            "array"   => [
                "a.time"       => ["asc" => "创建时间升序", "desc" => "创建时间降序", "site" => 2],
                "a.updateTime" => ["asc" => "更新时间升序", "desc" => "更新时间降序", "site" => 3],
            ],
        ]);
        $page    = $this->page([
            "table"   => "material as a",
            "field"   => "a.*",
            "where"   => " $where ",
            'pageNum' => 50,
            "order"   => $orderBy['orderBy'],
        ]);
        $result  = [];
        //获取记录
        foreach ($page['array'] as $array) {
            $inventoryNum = inventoryBalanceClass::inventoryNum($array['id']);
            $result[]     = [
                'materialId'      => $array['id'],
                'name'            => $array['code'] . ' ' . $array['name'] . $array['model'],
                'model'           => $array['model'],
                'num'             => $inventoryNum,
                'unit'            => $array['unit'],
                'availableNum'    => $inventoryNum,
            ];
        }
        $orderByArr         = [
            '创建时间降序',
            '创建时间升序',
            '更新时间降序',
            '更新时间升序',
        ];
        $this->resp['data'] = [
            'result'  => $result,
            'page'    => $page['para'],
            'orderBy' => $orderByArr,
        ];
        $this->code         = 1;
    }

    /**
     * 根据是否含税计算价税合计和税额
     */
    public static function isTax($num, $price, $rate, $isTax = 0): array
    {
        $money = $moneyWithTax = $taxMoney = 0;
        if (!isZero($num, $price)) {
            if ($isTax) {
                //含税
                $moneyWithTax = self::formattingFigure($num * $price, 'amount');
                $taxMoney     = self::formattingFigure($moneyWithTax / (1 + $rate) * $rate, 'amount');
            } else {
                //不含税
                $taxMoney     = self::formattingFigure($num * $price * $rate, 'amount');
                $moneyWithTax = self::formattingFigure($num * $price * (1 + $rate), 'amount');
            }
            $money = $moneyWithTax - $taxMoney;
        }
        return ['money' => $money, 'taxMoney' => $taxMoney, 'moneyWithTax' => $moneyWithTax];
    }

    /**
     * 编辑
     */
    public function edit(): void
    {
        // 解析字符串
        $detail           = !empty($_POST['detail']) ? json_decode($_POST['detail'], true) : [];
        $id               = $this->post('id') ?: self::getId();
        $mxIdArr          = $this->post('mxId') ?: inStockClass::getArrVal('id', $detail);
        $materialIdArr = $this->post('materialId') ?: inStockClass::getArrVal('materialId', $detail);
        $unitArr          = $this->post('unit') ?: inStockClass::getArrVal('unit', $detail);
        $numArr           = $this->post('num') ?: inStockClass::getArrVal('num', $detail);
        $priceArr         = $this->post('price') ?: inStockClass::getArrVal('price', $detail);
        $mxTextArr        = $this->post('mxText') ?: inStockClass::getArrVal('mxText', $detail);
        $rateArr          = $this->post('rate') ?: inStockClass::getArrVal('rate', $detail);

        $field      = [
            'type'         => $this->post('type'),
            'khid'         => $this->post('khid'),
            'recordDate'   => $this->post('recordDate'),
            'delivery_method'   => $this->post('delivery_method') ?: 1,
            'settlementType'   => $this->post('settlementType'),
            'deliveryDate' => $this->post('deliveryDate'),
            'isTax'           => $this->post('isTax'),
            'text'         => $this->post('text'),
        ];
        $annotation = [
            'khid'         => '客户',
            'delivery_method'   => '交货方式',
            'settlementType'   => '结算方式',
            'recordDate'   => '单据日期',
            'deliveryDate' => '交货日期',
            'text'         => '备注',
        ];
        $rules      = [
            'type'         => 'required',
            'khid'         => 'required',
            'delivery_method'         => 'required',
            'settlementType'         => 'required',
            'recordDate'   => 'required|date',
            'deliveryDate' => 'required|date',
            // 'text'           => 'required',
        ];
        // 校验是否符合规则
        $vt     = new verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $this->resp['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        }
        $where = " coid = '" . self::$coid . "' AND id = '$id' ";
        $info  = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $this->resp['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (self::is_null_array($mxIdArr)) {
            $this->resp['warn'] = '请选择产品明细';
        } elseif (self::is_null_array($materialIdArr)) {
            $this->resp['warn'] = '请选择产品明细';
        } elseif (self::is_null_array($numArr)) {
            $this->resp['warn'] = '数量请填写完整';
        } elseif (self::is_null_array($priceArr)) {
            $this->resp['warn'] = '价格请填写完整';
        } elseif (self::is_null_array($unitArr)) {
            $this->resp['warn'] = '请选择主单位';
        } elseif (self::is_null_array($rateArr)) {
            $this->resp['warn'] = '请输入税率';
        } elseif (!empty($info['id']) && $info['state'] == '已确认') {
            $this->resp['warn'] = '此销售单已确认，不能修改';
        } else {
            $this->startTrans();
            $isPass = true;//事务通过标志
            if (!$info['id']) {
                $orderNo            = self::generateCode(self::page, [
                    'prefix' => 'XSDD' . date('Ymd'),
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => '',
                ], $field);
                $field              = array_merge($field, [
                    'id'      => $id,
                    'orderNo' => $orderNo,
                    'state'   => '草稿',
                    'manager' => $this->control['stid'],
                    'coid'    => self::$coid,
                    'stid'    => $this->control['stid'],
                ]);
                $this->resp['warn'] = static::insert(["table" => self::table, "field" => $field,]);
            } else {
                $this->resp['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where,
                ]);
            }
            //添加或更新销售单明细
            if (is_array($mxIdArr)) {
                foreach ($mxIdArr as $k => $nid) {
                    $mx          = query(self::tableMx, "id = '$nid'");
                    $numArr[$k]   = self::formattingFigure($numArr[$k], 'numPrecision');
                    $priceArr[$k] = self::formattingFigure($priceArr[$k], 'pricePrecision');
                    $result         = self::isTax($numArr[$k], $priceArr[$k], $rateArr[$k], $field['isTax']);
                    if (!empty($mx['id'])) {
                        //更新
                        $warn = static::update([
                            "table" => self::tableMx,
                            "field" => [
                                'materialId'    => $materialIdArr[$k],
                                'num'           => $numArr[$k],
                                'price'         => $priceArr[$k],
                                'coid'          => self::$coid,
                                'rate'          => $rateArr[$k],
                                'taxMoney'           => $result['taxMoney'],//税额
                                'moneyWithOutTax'    => $result['money'],//不含税金额
                                'money'    => $result['moneyWithTax'],//不含税金额
                                'text'          => $mxTextArr[$k],
                            ],
                            "where" => " id = '$nid'",
                        ]);
                    } else {
                        //新增
                        $warn = static::insert([
                            "table" => self::tableMx,
                            "field" => [
                                'id'            => $nid,
                                'coid'          => self::$coid,
                                'orderId'       => $id,
                                'materialId'    => $materialIdArr[$k],
                                'num'           => $numArr[$k],
                                'price'         => $priceArr[$k],
                                'rate'          => $rateArr[$k],
                                'taxMoney'           => $result['taxMoney'],//税额
                                'moneyWithOutTax'    => $result['money'],//不含税金额
                                'money'    => $result['moneyWithTax'],//不含税金额
                                'text'          => $mxTextArr[$k],
                            ],
                        ]);
                    }
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $isPass             = false;
                        $this->resp['warn'] = $warn;
                        break;
                    }
                }
            }
            if (in_array($this->resp['warn'], ["新增成功", "更新成功"]) && $isPass) {
                $this->commitTrans();
                // 更新金额
                static::update([
                    'table' => self::table,
                    'field' => [
                        'money' => self::total([
                            'sql' => " SELECT IFNULL(sum(money), 0) AS total FROM `" . self::tableMx . "` WHERE orderId = '$id' ",
                        ]),
                    ],
                    'where' => " id = '$id' ",
                ]);
                delete(['table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"]);
                //添加日志
                $type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $this->code         = 1;
                $this->resp['data'] = $id;
            } else {
                $this->rollback();
            }
        }

        resp:
    }

    /**
     * 提交
     */
    public function commit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
        $field = [
            'state' => '待确认',
        ];
        if (!$this->power(self::page, 'edit')) {
            $this->resp['warn'] = '你还没有编辑权限';
        } elseif (empty($info['id'])) {
            $this->resp['warn'] = '未找到此销售单';
        } elseif ($info['state'] != '草稿') {
            $this->resp['warn'] = '此销售单不是草稿状态，不能提交';
        } else {
            $this->resp['warn'] = update(array(
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ));
            if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
                auditingFollow([
                    "type"   => "销售单",
                    "typeId" => $info['id'],
                    "text"   => "【{$this->control['name']}】提交",
                ]);
                //添加日志
                $type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $this->code = 1;
            }
        }
        resp:
    }

    /**
     * 确认
     */
    public function confirmEdit()
    {
        $id    = $this->post('id');
        $info  = query(self::table, " coid = '" . self::$coid . "' AND id = '$id'");
        $field = [
            'state'       => '已确认',
            'checkId'     => self::$stid,
            'confirmTime' => $this->time,
        ];
        if (!$this->power(self::page, 'confirm')) {
            $this->resp['warn'] = '你还没有确认权限';
        } elseif (empty($info['id'])) {
            $this->resp['warn'] = '未找到此销售单';
        } elseif ($info['state'] != '待确认') {
            $this->resp['warn'] = '此申请不是待确认状态，不能确认';
        } else {
            $this->resp['warn'] = update([
                "table" => self::table,
                "field" => $field,
                "where" => "id = '$info[id]'",
            ]);
            if (in_array($this->resp['warn'], ["新增成功", "更新成功"])) {
                auditingFollow(array(
                    "type"   => "销售单",
                    "typeId" => $info['id'],
                    "text"   => "【{$this->control['name']}】确认",
                ));
                //添加日志
                $type = mb_substr($this->resp['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $this->code = 1;
            }
        }

        resp:
    }

    /**
     * 删除
     *
     * @return void
     */
    public function delete(): void
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $this->resp['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $this->resp['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] == '已确认') {
                    $warn = "删除失败：已确认，暂不能删除";
                } else {
                    //最后删除基本参数
                    delete(["table" => self::table, "where" => " id = '$id' "]);
                    delete(["table" => self::tableMx, "where" => " orderId = '$id' "]);
                    delete(["table" => 'auditing_follow', "where" => " typeId = '$id' "]);
                    //返回
                    $warn = "删除成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $this->resp['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $this->code         = 1;
        }
    }


    /**
     * 详情
     *
     * @return void
     */
    public function detail()
    {
        $id   = $this->post('id');
        $info = query(self::table, "id = '" . $id . "'");
        if (empty($id)) {
            $this->resp['warn'] = "ID为空";
        } elseif (empty($info['id'])) {
            $this->resp['warn'] = "未找到此" . self::title;
        } else {
            $target = query(self::tableTarget, " khid = '$info[khid]' ");
            $audit  = find([
                'table' => 'auditing_follow',
                'where' => " typeId = '$info[id]' order by time desc",
            ]);
            $result = find([
                'table' => self::tableMx,
                'where' => " orderId = '$info[id]' ",
            ]);
            $detail = $tracking = [];
            // 总的价税合计
            $totalMoney = 0;
            foreach ($result['array'] as $value) {
                $material    = query('material', " id = '$value[materialId]' ");
                $detail[]    = [
                    'id'              => $value['id'],
                    'code'            => $material['code'],
                    'name'            => $material['name'],
                    'model'           => $material['model'],
                    'unit'            => $material['unit'],
                    'price'           => $value['price'],
                    'num'             => self::lostZero($value['num'], 'num'),
                    'rate'            => $value['rate'],
                    'text'            => $value['text'],
                    'materialId'      => $value['materialId'],
                    'moneyWithOutTax' => self::lostZero($value['moneyWithOutTax']),
                    'taxMoney'        => self::lostZero($value['taxMoney']),
                    'total'           => self::lostZero($value['money']),
                ];
                $totalMoney  += $value['money'];
                // 退货数量
                /*$retrunSql = " SELECT IFNULL(SUM(num), 0) as total FROM `sale_refund_order_detail`";
                $mWhere    = generateWhere([
                    'saleOrderMxId' => $value['id'],
                    'materialId' => $value['materialId'],
                ]);
                // 合同退货
                $returnContract = $info['contractId'] ? self::total([
                    'sql'   => $retrunSql,
                    'where' => " materialId = '{$value['materialId']}' AND orderId IN (SELECT id FROM sale_refund_order WHERE contractId ='{$info['contractId']}' ) ",
                ]) : 0;
                // 销售发货单
                $sendTotal = self::total([
                    'sql'   => $retrunSql,
                    'where' => " materialId = '{$value['materialId']}' AND sourceId IN (SELECT id FROM sale_send_order_detail WHERE $mWhere ) ",
                ]);
                // 销售退货
                $sendTotal = self::total([
                    'sql'   => $retrunSql,
                    'where' => generateWhere([
                        'sourceId'      => $value['id'],
                        'materialId' => $value['materialId'],
                    ]),
                ]);*/

                // self::total([
                //						'sql'   => "SELECT IFNULL(SUM(num),0) AS total FROM `sale_send_order_detail` as d, `sale_send_order` as o ",
                //						'where' => $mWhere . " AND o.id = d.orderId AND o.state = '已确认' ",
                //					])
                $tracking[] = [
                    'name'   => $material['code'] . ' ' . $material['name'] . $material['model'],
                    'total'  => (float)$value['num'],
                    'send'   => (float)$value['refund_num'],
                    'return' => (float)$value['refund_num'],
                ];
            }
            $delivery = ['1' => '自提', '2' => '配送'];
            $data['result'] = [
                'info'        => [
                    "id"           => $info['id'],
                    'manager'      => self::findStaff($info['manager']),
                    'staffName'    => self::findStaff($info['stid']),
                    'orderNo'      => $info['orderNo'],
                    'recordDate'   => $info['recordDate'],
                    'delivery_method' => $info['delivery_method'],
                    'delivery_method_text' => $delivery[$info['delivery_method']]??'',
                    'settlementType' => $info['settlementType'],
                    'deliveryDate' => $info['deliveryDate'],
                    'type'         => $info['type'],
                    'target'       => $target ? $target['companyName'] : '',
                    'targetId'     => $target ? $target['khid'] : '',
                    "state"        => $info['state'],
                    'text'         => $info['text'],
                    'isTax'         => $info['isTax'],
                    'date'         => self::formatDate($info['time'], 'm/d'),
                ],
                'detail'      => $detail,
                'auditRecord' => $audit['array'],
                'tracking'    => $tracking,
                'total'       => [
                    'num'   => count($detail),
                    'money' => $totalMoney,
                ],
            ];
            //返回
            $this->code         = 1;
            $this->resp['data'] = $data;
        }
    }

}
